<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2021/08/28
 * Time: 21:47
 * @link http://www.lmterp.cn
 */

namespace app\command;

use app\common\library\Tools;
use app\common\model\Channel;
use app\common\model\ChannelCountrySettings;
use app\common\model\ChannelOrders;
use think\console\input\Option;
use think\facade\Log;

/**
 * 统计物流时效
 * Class StatLogistics
 * @package app\command
 */
class StatLogistics extends BaseCommand
{

    /**
     * 开始统计时间，默认为前一个月
     * @var string
     */
    private $startDate;

    /**
     * 结束统计时间，默认为今天
     * @var string
     */
    private $endDate;

    protected function configure()
    {
        $this->setName('stat_logistics')
            ->addOption("start_date", null, Option::VALUE_REQUIRED, "开始统计时间，默认为昨天")
            ->addOption("end_date", null, Option::VALUE_REQUIRED, "结束统计时间");
    }

    protected function handler()
    {
        $this->startDate = $this->input->hasOption("start_date")
                ? $this->input->getOption("start_date")
                : date("Y-m-d", strtotime("-1month"));
        $this->endDate = $this->input->hasOption("end_date")
                ? $this->input->getOption("end_date")
                : Tools::addDate(1);
        Log::info("开始统计【{$this->startDate} - {$this->endDate}】物流订单");
        $this->avgDay();
        $this->successRate();
        Log::info("完成统计【{$this->startDate} - {$this->endDate}】物流订单");
    }

    /**
     * 统计渠道走每个国家的物流时效
     * @date 2021/08/28
     * @author longli
     */
    private function avgDay()
    {
        $where = [
            ["track_status", "eq", ChannelOrders::TRACK_STATUS_RECV],
            ["create_time", "egt", $this->startDate],
            ["create_time", "elt", $this->endDate],
        ];
        $orders = ChannelOrders::where($where)
            ->field(["avg(shipping_day) avg_day", "channel_id", "country_code"])
            ->group("channel_id, country_code")
            ->having("avg_day > 0")
            ->select();
        foreach($orders as $order)
        {
            $setting = ChannelCountrySettings::get(["channel_id" => $order->channel_id, "country_code" => $order->country_code]);
            if(empty($setting)) continue;
            $setting->avg_day = round($order->avg_day, 2);
            $setting->save();
        }
    }

    /**
     * 统计每个国家及整体的妥投率
     * @date 2021/08/28
     * @author longli
     */
    private function successRate()
    {
        $where = [
            ["create_time", "egt", $this->startDate],
            ["create_time", "elt", $this->endDate],
        ];
        $totalSql = ChannelOrders::field(["count(order_id) total", "channel_id", "country_code"])
            ->where($where)
            ->whereIn("track_status", [
                ChannelOrders::TRACK_STATUS_RECV, ChannelOrders::TRACK_STATUS_TIMEOUT,
                ChannelOrders::TRACK_STATUS_UNRECV, ChannelOrders::TRACK_STATUS_EXCEPTION,
            ])
            ->group("channel_id, country_code")
            ->buildSql();
        $orders = ChannelOrders::where("track_status",ChannelOrders::TRACK_STATUS_RECV)
            ->where($where)
            ->alias("o")
            ->field(["count(order_id) succ", "o.channel_id", "o.country_code", "t.total"])
            ->join("$totalSql t", "o.channel_id = t.channel_id and o.country_code=t.country_code")
            ->group("o.channel_id, o.country_code")
            ->order("o.channel_id")
            ->select();

        $fun = function($total, $succ, $obj)
        {
            if($succ > 0 && $total > 0 && $obj)
            {
                $obj->save([
                    "success_rate" => round($succ / $total, 2) * 100
                ]);
            }
        };
        $cid = $total = $succ = 0;
        foreach($orders as $order)
        {
            if(empty($cid)) $cid = $order->channel_id;
            if($cid != $order->channel_id)
            {
                $fun($total, $succ, Channel::get($cid));
                $succ = $total = 0;
                $cid = $order->channel_id;
            }
            $total += $order->total;
            $succ += $order->succ;
            $fun($order->total, $order->succ, ChannelCountrySettings::get([
                "channel_id" => $order->channel_id,
                "country_code" => $order->country_code
            ]));
        }
        $fun($total, $succ, Channel::get($cid));
    }
}